package tools

import (
	"fmt"
	RawCAN "github.com/linklayer/go-socketcan/pkg/socketcan"
	"io"
	"time"
)

type replayFrame struct {
	timeStamp int64
	RawCAN.CanFrame
}

type repeater struct {
	// 读取文件用的fd
	fd *Fd
	// 上一轮发送的第一条报文
	last int64
	// canInstance
	c *Can
	// 标记第一帧是否已发送
	first bool
	// 序列化器, 用于反序列化
	serialization Serialization
}

func RepeaterInit(c *Can, fileName string) *repeater {
	fd := FdInit(fileName)
	return &repeater{
		fd:            fd,
		c:             c,
		first:         true,
		serialization: &defaultSerialization{},
	}
}

func (r *repeater) Handler() {
	r.fd.Handler()
}

func (r *repeater) Replay() {
	replayCh := make(chan replayFrame, 0)

	go func(ch chan<- replayFrame) {
		// if EOF: close channel

		i := 0
		for {
			frameString, readerError := r.fd.Reader.ReadString('\n')
			if readerError == io.EOF {
				close(ch)
				return
			}
			i++
			ch <- *deserialize(frameString)
		}
	}(replayCh)
	r.send(replayCh)
}

func (r *repeater) send(replayCh <-chan replayFrame) {
	var start, Interval int64
	frame, ok := <-replayCh
	r.last = frame.timeStamp // 第一帧的时间戳
	start = time.Now().UnixNano()

	for {
		time.Sleep(time.Millisecond)
		Interval = time.Now().UnixNano() - start
		curSent := false
		var firstFrame replayFrame
		for {
			if !ok {
				if frame.timeStamp-r.last < Interval {
					// 如果是本轮第一次, 那么更新start
					if !curSent {
						start = time.Now().UnixNano()
						firstFrame = frame
						curSent = true
					}
					//send
					r.c.Send(frame.CanFrame)
					frame, ok = <-replayCh // 获取下一个帧
				} else {
					// 将last更新一下， 如果这一轮有发送过帧的话, 没有就不用更新了
					if curSent {
						r.last = firstFrame.timeStamp
					}
					break
				}
				continue
			}
			fmt.Println("send complete")
			return
		}
	}
}

func (r *repeater) RegisterSerialization(serialization Serialization) {
	r.serialization = serialization
	return
}
